#include "line.h"
#include "windows.h"
#include "cmath"
Lines::Lines(Clarity::SceneManager *sm)
{
	m_sceneManager = sm;
};

Lines::~Lines()
{
	clear();
}

void Lines::setSceneManager(Clarity::SceneManager *sm)
{
	m_sceneManager = sm;
}

void Lines::addLine(Clarity::Vector2 start, Clarity::Vector2 end, int red, int green, int blue)
{
	if(m_sceneManager)
	{
		Clarity::LineSegment2 line(start,end);
		Clarity::RenderableLineSegment *r = new Clarity::RenderableLineSegment(m_sceneManager->GetRenderSystem(), line);
		r->GetMaterial()->SetDiffuse(Clarity::Colour(red,green,blue));
		m_sceneManager->GetRoot()->AttachObject(r);
		m_lines.push_back(r);
	}
}
void Lines::addCircle(Clarity::Vector2 pos, float radius, int red, int green, int blue)
{
	if(m_sceneManager)
	{
		Clarity::Vector2 last(cos(0.0)*radius+pos.x,sin(0.0)*radius+pos.y);
		for(float a=0;a<3.14159265*2.0;a+=3.14159265*2.0/32.0)
		{
			Clarity::Vector2 now(cos(a)*radius+pos.x,sin(a)*radius+pos.y);
			addLine(last,now,red,green,blue);
			last=now;
		}
		addLine(last,Clarity::Vector2(cos(0.0)*radius+pos.x,sin(0.0)*radius+pos.y),red,green,blue);
	}
}

void Lines::clear()
{
	if(m_sceneManager)
	{
		for(int i=0;i<m_lines.size();i++)
		{
			Clarity::SceneNode::ObjectIterator it = m_sceneManager->GetRoot()->GetAttachedObject(m_lines[i]->GetName());
			m_sceneManager->GetRoot()->DetachObject(it);
			delete m_lines[i];
		}
		m_lines.clear();
	}
}

GridNode::GridNode()
{
	m_wall = false;
}

Grid::Grid()
{
	m_data = 0;
}
Grid::~Grid()
{
	delete m_data;
}

void Grid::setup(const AIHarness::AgentInitData &agentInitData, float gridsize)
{
	m_lines.setSceneManager(agentInitData.sceneManager);
	x1 = agentInitData.arenaBounds.GetMinimum().x;
	x2 = agentInitData.arenaBounds.GetMaximum().x;
	y1 = agentInitData.arenaBounds.GetMinimum().y;
	y2 = agentInitData.arenaBounds.GetMaximum().y;
	m_columns = ceil((x2-x1)/gridsize);
	m_rows = ceil((y2-y1)/gridsize);
	m_gridsize = gridsize;
	for(int y = 0; y<m_rows; y++)
	{
		m_lines.addLine(Clarity::Vector2(x1,y1+m_gridsize*y), Clarity::Vector2(x2,y1+m_gridsize*y));
	}
	for(int x = 0; x<m_columns; x++)
	{
		m_lines.addLine(Clarity::Vector2(x1+m_gridsize*x,y1), Clarity::Vector2(x1+m_gridsize*x,y2));
	}
	m_data = new GridNode[m_columns*m_rows];

   std::vector<Clarity::AARect>::const_iterator it;
   std::vector<Clarity::AARect>::const_iterator itEnd = agentInitData.walls.end();

   for (it = agentInitData.walls.begin(); it != itEnd; ++it)
   {
      const Clarity::AARect &rect = *it;
		int xx1, yy1, xx2, yy2;
		mapToGrid(rect.GetMinimum(), xx1, yy1);
		mapToGrid(rect.GetMaximum(), xx2, yy2);
		for(int y=yy1;y<yy2;y++)
		{
			for(int x=xx1;x<xx2;x++)
			{
				Clarity::Vector2 w = getGridPos(x,y);
				m_lines.addLine(w+Clarity::Vector2(-5,-5),w+Clarity::Vector2(5,5),255,255,0);
				m_lines.addLine(w+Clarity::Vector2(5,-5),w+Clarity::Vector2(-5,5),255,255,0);
				getNode(x,y).m_wall = true;
			}
		}
	}
}

void Grid::render()
{
}

Clarity::Vector2 Grid::getGridPos(int x, int y)
{
	return Clarity::Vector2(x1+(x+0.5)*m_gridsize, y1+(y+0.5)*m_gridsize);
}

void Grid::mapToGrid(Clarity::Vector2 pos, int &x, int &y)
{
	x = (pos.x-x1)/m_gridsize;
	y = (pos.y-y1)/m_gridsize;
}

GridNode &Grid::getNode(int x, int y)
{
	return m_data[x+m_columns*y];
}

int Grid::getRows()
{
	return m_rows;
}

int Grid::getColumns()
{
	return m_columns;
}
